package com.kly.order.serviceImpl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.fqgj.common.api.Response;
import com.fqgj.common.utils.StringUtils;
import com.fqgj.log.factory.LogFactory;
import com.fqgj.log.interfaces.Log;
import com.google.api.client.util.Lists;
import com.kly.dto.*;
import com.kly.enums.Benefits;
import com.kly.enums.ProductCategory;
import com.kly.enums.TradeResultStatus;
import com.kly.order.ServiceUtils;
import com.kly.order.db.dao.ConsumptionRecordDao;
import com.kly.order.db.dao.MemberDao;
import com.kly.order.db.dao.ProductBenefitsDao;
import com.kly.order.db.dao.UserVasPurchasesDao;
import com.kly.order.db.dbo.UserPCountDBO;
import com.kly.order.db.entity.ConsumptionRecordEntity;
import com.kly.order.db.entity.ProductBenefitsEntity;
import com.kly.order.db.entity.UserVasPurchasesEntity;
import com.kly.order.mapper.MemberBenefitsMapper;
import com.kly.order.mapper.ProductMapper;
import com.kly.order.mapper.UserVasPurchasesMapper;
import com.kly.pay.task.PayCallBackTask;
import com.kly.req.UserConsumeRequest;
import com.kly.service.UserVasPurchasesService;
import com.kly.user.dto.chatter.response.UserChatterModeDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service("userVasPurchasesService")
public class UserVasPurchasesServiceImpl implements UserVasPurchasesService {
    private static Log logger = LogFactory.getLog(UserVasPurchasesServiceImpl.class);
    @Autowired
    UserVasPurchasesDao userVasPurchasesDao;

    @Autowired
    UserVasPurchasesMapper mapper;

    @Resource
    private ProductBenefitsDao productBenefitsDao;

    @Autowired
    ProductMapper productMapper;

    @Resource
    ConsumptionRecordDao consumptionRecordDao;

    @Resource
    MemberDao memberDao;

    private static final Integer ZERO=0;
    /**
     * 获取用户增值权益
     *
     * @param userCode    用户码
     * @param benefitCode 服务类型，如果为空则查询用户全部购买的服务
     * @return 用户购买权益集合
     */
    @Override
    public Response<List<UserVasPurchasesDto>> getUserPurchasesBenefits(String userCode, Integer benefitCode) {

        List<UserVasPurchasesEntity> memberBenefitsEntities = getUserBenefits(userCode, benefitCode,1);

        if (memberBenefitsEntities == null || memberBenefitsEntities.isEmpty()) {
            return Response.error(TradeResultStatus.NO_AVAILABLE_BENEFITS);
        }

        List<UserVasPurchasesDto> benefitsDtoList = memberBenefitsEntities.stream()
                .map(mapper::toDto)
                .collect(Collectors.toList());

        return Response.ok(benefitsDtoList);

    }

    @Override
    public Response<List<UserVasPurchasesDto>> getAllUserBenefits(String userCode) {

        List<UserVasPurchasesEntity> memberBenefitsEntities = userVasPurchasesDao.queryBenefitsByUserCode(userCode);

        if (memberBenefitsEntities == null || memberBenefitsEntities.isEmpty()) {
//            return Response.error(TradeResultStatus.NO_AVAILABLE_BENEFITS);
            return Response.ok(Lists.newArrayList());
        }

        List<UserVasPurchasesDto> benefitsDtoList = memberBenefitsEntities.stream()
                .map(mapper::toDto).collect(Collectors.toList());

        return Response.ok(benefitsDtoList);
    }


    /**
     * 添加用户增值服务使用次数
     *
     * @param userCode 用户码
     * @param product  购买产品
     * @return 添加结果
     */
    @Override
    public Response<String> saveUserPurchasesBenefits(String userCode, ProductDto product) {
        List<ProductBenefitsEntity> productBenefits = productBenefitsDao.listProductBenefit(product.getAppCode(), product.getProductCategory());

        List<Benefit> benefits = new ArrayList<>();
        for (ProductBenefitsEntity productBenefit : productBenefits) {
            Benefit benefit = productMapper.toBenefit(productBenefit);
            if (product.getProductQuantity()!=null&&product.getProductQuantity()>ZERO){
                benefit.setMaxSize(product.getProductQuantity());
            }
            benefits.add(benefit);
        }
        logger.info("saveUserPurchasesBenefits, productBenefits:{}", productBenefits);

        for (Benefit benefit : benefits) {
            //查询用户
            List<UserVasPurchasesEntity> userBenefits = getUserBenefits(userCode, benefit.getBenefitCode(),2);
            logger.info("saveUserPurchasesBenefits, userBenefits:{}", userBenefits);
            //如果存在购买记录则添加使用次数、否则新增记录
            if (userBenefits == null || userBenefits.isEmpty()) {
                UserVasPurchasesEntity userVasPurchases = new UserVasPurchasesEntity();
                userVasPurchases.setUserCode(userCode);
                userVasPurchases.setStartDate(new Date());
                userVasPurchases.setEndDate(DateUtil.parse("2099-01-01"));
                if (Benefits.NUMBER_OF_USERS_BROWSED.getBenefitCode() == benefit.getBenefitCode()
                        || Benefits.NUMBER_OF_USERS_LIKED.getBenefitCode() == benefit.getBenefitCode()
                        || Benefits.ICE_BREAKING_SESSION.getBenefitCode() == benefit.getBenefitCode()
                ) {
                    userVasPurchases.setUsageCount(0);
                    userVasPurchases.setAdditionalBenefitCount(benefit.getMaxSize());
                    userVasPurchases.setAdditionalStartDate(new Date());
                    userVasPurchases.setAdditionalEndDate(DateUtil.endOfDay(new Date()));
                } else {
                    userVasPurchases.setAdditionalBenefitCount(0);
                    userVasPurchases.setUsageCount(benefit.getMaxSize());

                }
                userVasPurchases.setBenefitCode(benefit.getBenefitCode());
                userVasPurchases.setBenefitName(benefit.getBenefitName());
                userVasPurchases.setAppCode(product.getAppCode());
                userVasPurchasesDao.insert(userVasPurchases);
            } else {
                UserVasPurchasesEntity userVasPurchases = userBenefits.get(0);

                if (Benefits.NUMBER_OF_USERS_BROWSED.getBenefitCode() == benefit.getBenefitCode()
                        || Benefits.NUMBER_OF_USERS_LIKED.getBenefitCode() == benefit.getBenefitCode()
                        || Benefits.ICE_BREAKING_SESSION.getBenefitCode() == benefit.getBenefitCode()){

                    // 当日已发放权益，则不再发放
                    final Date additionalStartDate = userVasPurchases.getAdditionalStartDate();
                    if (Objects.nonNull(additionalStartDate) && DateUtil.formatDate(additionalStartDate).equals(DateUtil.formatDate(new Date()))) {
                        continue;
                    }

                    userVasPurchases.setUsageCount(0);
                    userVasPurchases.setAdditionalBenefitCount(benefit.getMaxSize());
                    userVasPurchases.setAdditionalStartDate(new Date());
                    userVasPurchases.setAdditionalEndDate(DateUtil.endOfDay(new Date()));
                } else {
                    userVasPurchases.setAdditionalBenefitCount(0);
                    userVasPurchases.setUsageCount(userVasPurchases.getUsageCount() + benefit.getMaxSize());
                }
                userVasPurchasesDao.updateByPrimaryKey(userVasPurchases);
            }
        }

        return Response.ok();

    }

    /**
     * 扣减用户服务使用次数
     *
     * @param userBenefits 扣减用户服务Dto
     * @return 扣减结果
     */
    @Override
    public Response<String> reduceUserBenefits(ReduceBenefitsDto userBenefits) {
        List<UserVasPurchasesEntity> benefits =
                getUserBenefits(userBenefits.getUserCode(), userBenefits.getBenefitCode(),3);
        if (CollUtil.isEmpty(benefits)) {
            return Response.error(TradeResultStatus.NO_AVAILABLE_BENEFITS);
        }
        UserVasPurchasesEntity userVasPurchases = benefits.get(0);
        final int additionalBenefitCount = Objects.isNull(userVasPurchases.getAdditionalBenefitCount()) ? 0 : userVasPurchases.getAdditionalBenefitCount();
        if (additionalBenefitCount > 0) {
            userVasPurchases.setAdditionalBenefitCount(additionalBenefitCount - 1);
        } else {
            userVasPurchases.setUsageCount(userVasPurchases.getUsageCount() - 1);
        }
        Integer integer = userVasPurchasesDao.updateByPrimaryKey(userVasPurchases);
        if (integer > 0) {
            return Response.ok();
        } else {
            return Response.error(TradeResultStatus.NO_AVAILABLE_BENEFITS);
        }
    }

    /**
     * 添加
     * @param userBenefits
     */
    @Override
    public void addUserConsumptionRecord(ReduceBenefitsDto userBenefits) {
        log.info("addUserConsumptionRecord, userBenefits:{}", JSONObject.toJSONString(userBenefits));
        ConsumptionRecordEntity consumptionRecordEntity=new ConsumptionRecordEntity();
        BeanUtil.copyProperties(userBenefits,consumptionRecordEntity);
        String imageCode = userBenefits.getImageCode();

        consumptionRecordEntity.setImageCode(imageCode);
        consumptionRecordEntity.setImageUrl(userBenefits.getImageUrl());
        consumptionRecordEntity.setMsgId(userBenefits.getMsgId());

        try {
            consumptionRecordDao.insert(consumptionRecordEntity);
        }catch (Exception e){
            logger.info("addUserConsumptionRecord error , params:{},entity:{}", JSONUtil.toJsonStr(userBenefits),JSONUtil.toJsonStr(consumptionRecordEntity),e);
        }

    }

    @Override
    public boolean getUnlock(String userCode, String chatUserCode, String imageCode) {
        boolean result = false;
        ConsumptionRecordEntity consumptionRecordEntity = consumptionRecordDao.getLastRecord(userCode, chatUserCode, imageCode);
        if (consumptionRecordEntity != null) {
            long hour = cn.hutool.core.date.DateUtil.between(consumptionRecordEntity.getGmtCreate(), new Date(), DateUnit.HOUR);
            if (hour > 1) {
                result = true;
            }
        }
        return result;
    }

    @Override
    public int updateUsageCount(int usageCount, String userCode, int benefitCode) {
        return userVasPurchasesDao.updateUsageCount(usageCount, userCode, benefitCode);
    }


    @Override
    public int getUserConsumptionRecord(UserConsumeRequest request) {
        Map<String,Object> queryMap = new HashMap<>();
        queryMap.put("userCode",request.getUserCode());
        queryMap.put("imageCode",request.getImageCode());
        List<ConsumptionRecordEntity> consumptionRecordEntities = consumptionRecordDao.selectByParams(queryMap);

        //1小时内存在的话做防重处理
        List<ConsumptionRecordEntity> filterList = consumptionRecordEntities.stream().filter(x-> DateUtil.between(x.getGmtCreate(),new Date(),DateUnit.MINUTE)<50).collect(Collectors.toList());

        //0代表不做处理
        if(filterList.isEmpty()){
            return 0;
        }
        return filterList.size();
    }

    @Override
    public int getUnlockCount(String userCode, String chatUserCode, String imageCode) {
        return consumptionRecordDao.getUnlockCount(userCode, chatUserCode, imageCode);
    }

    @Override
    public List<ConsumptionUserDto> unLockList(String chatUserCode) {
        List<ConsumptionRecordEntity> consumptionRecordEntityList = consumptionRecordDao.unLockList(chatUserCode);
        return consumptionRecordEntityList.stream()
                .map(entity -> {
                    ConsumptionUserDto consumptionUserDto = new ConsumptionUserDto();
                    consumptionUserDto.setChatUserCode(entity.getChatUserCode());
                    consumptionUserDto.setUserCode(entity.getUserCode());
                    return consumptionUserDto;
                }).collect(Collectors.toList());
    }

    public List<UserVasPurchasesEntity> getUserBenefits(String userCode, Integer benefitCode,Integer queryFlag) {
        Map<String, Object> map = new HashMap<>();
        map.put("date", new Date());
        map.put("userCode", userCode);
        map.put("deleted", 0);
        if (Objects.nonNull(benefitCode)) {
            map.put("benefitCode", benefitCode);
        }
        map.put("usageCount", queryFlag);
        return userVasPurchasesDao.selectByUserCode(map);
    }

    @Override
    public Response<List<UserPCountDto>> getUserPCount(String chatterUserCode, String startDate, String endDate) {
        List<UserPCountDBO> userPCountDBOS = consumptionRecordDao.listUnlockNum(chatterUserCode, startDate, endDate);
        return Response.ok(UserPCountDBO.toDto(userPCountDBOS));
    }
}
